﻿using System;
using System.Collections.Generic;
using System.Linq;
using GC_FFW.BusinessEntities.Abstractions.Interfaces.Forecast;
using GC_FFW.BusinessEntities.Abstractions.Interfaces.Soccerfame;
using GC_FFW.BusinessEntities.Enums.Soccerfame;
using GC_FFW.BusinessEntities.Forecast;
using GC_FFW.SoccerfameParser.Abstractions.Interfaces.Builders;
using GC_FFW.SoccerfameParser.Abstractions.Interfaces.Factories;
using IMatch = GC_FFW.BusinessEntities.Abstractions.Interfaces.Forecast.IMatch;

namespace GC_FFW.SoccerfameParser.Builders
{
	public class ForecastDataBuilder : IForecastDataBuilder
	{
		#region Variables

		private readonly IAdapterFactory _adapterFactory;

		#endregion

		#region Constructors

		public ForecastDataBuilder(IAdapterFactory adapterFactory)
		{
			if (adapterFactory == null)
				throw new ArgumentNullException(string.Format("Adapter Factory"));
			_adapterFactory = adapterFactory;
		}

		#endregion

		#region IForecastDataBuilder Members

		public IForecastData Generate(string url)
		{
			var result = new ForecastData
			{
				HomeTeam = GenerateTeamInfo(url, true),
				AwayTeam = GenerateTeamInfo(url, false),
				PersonalConfrontationStatistics = GeneratePersonalConfrontationStatistics(url)
			};

			result.PersonalConfrontationStatistics.HomeTeamName = result.HomeTeam.Name;
			result.PersonalConfrontationStatistics.AwayTeamName = result.AwayTeam.Name;

			return result;
		}

		public ITeam GenerateTeamInfo(string url, bool isHomeTeam)
		{
			var adapter = _adapterFactory.CreateFutureMatchAdapter();
			if (adapter == null) return null;

			var result = new Team();

			var teamInfo = adapter.GetTeamInfo(url, isHomeTeam);
			result.Name = teamInfo != null ? teamInfo.Name : string.Empty;

			var teamMatches = (adapter.GetMatches(url, isHomeTeam) ?? new List<BusinessEntities.Abstractions.Interfaces.Soccerfame.IMatch>()).ToList();
			result.LastMatches = new List<IMatch>(teamMatches.Select(
				m => new Match
				{
					HomeTeamName = m.HomeTeam != null ? m.HomeTeam.Name : string.Empty,
					AwayTeamName = m.AwayTeam != null ? m.AwayTeam.Name : string.Empty,
					Date = m.Date,
					HomeTeamGoalsCount = m.HomeTeamGoalsCount,
					AwayTeamGoalsCount = m.AwayTeamGoalsCount
				}));

			return result;
		}

		public IPersonalConfrontationStatistics GeneratePersonalConfrontationStatistics(string url)
		{
			var adapter = _adapterFactory.CreateFutureMatchAdapter();
			if (adapter == null) return null;

			var result = new PersonalConfrontationStatistics();

			var teamMatches = (adapter.GetMatches(url, null) ?? new List<BusinessEntities.Abstractions.Interfaces.Soccerfame.IMatch>()).ToList();

			result.Matches = new List<IMatch>(teamMatches.Select(
				m => new Match
				{
					HomeTeamName = m.HomeTeam != null ? m.HomeTeam.Name : string.Empty,
					AwayTeamName = m.AwayTeam != null ? m.AwayTeam.Name : string.Empty,
					Date = m.Date,
					HomeTeamGoalsCount = m.HomeTeamGoalsCount,
					AwayTeamGoalsCount = m.AwayTeamGoalsCount
				}));

			var matchAdapter = _adapterFactory.CreateMatchAdapter();
			if (matchAdapter == null) return result;

			var lastMatch = teamMatches.OrderByDescending(m => m.Date).FirstOrDefault();

			if (result.LastTeamMatch != null && lastMatch != null && lastMatch.MatchResult != null)
			{
				var goals = (matchAdapter.GetEvents(lastMatch.MatchResult.Url, new List<EventType>
				{
					EventType.OwnGoal,
					EventType.Penalty,
					EventType.RegularGoal
				}) ?? new List<IEvent>()).ToList();

				result.LastTeamMatch.Goals = new List<IGoal>(goals.Select(
					g => new Goal
					{
						Goalscorer = g.Player != null ? g.Player.Name : string.Empty,
						IsHomeTeamGoal = g.IsHomeTeamEvent,
						Time = g.Time
					}));
			}

			return result;
		}

		#endregion
	}
}
